package me.olook.netease.song.rank.util;

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import me.olook.netease.song.rank.entity.WeiboUser;
import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author zhaohw
 * @date 2018-05-22 11:36
 */
public class WeiBoUtil {

    private static Logger log = LoggerFactory.getLogger(WeiBoUtil.class);

    private static int size = 1000;

    private static BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), size);

    private static CookieStore loginCookie = new BasicCookieStore();

    private static HttpClient httpClient = HttpClientBuilder.create().setDefaultCookieStore(loginCookie).build();


    /**
     * 移动端搜索
     * @param keyWord search keyword
     * @param page page number
     * @return JsonStr Result
     */
    public static String mobileSearch(String keyWord ,Integer page){
        String keywordParam = null;
        try {
            keywordParam = URLEncoder.encode(keyWord,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            log.error("UnsupportedEncodingException：{}",e.getMessage());
            return null;
        }
        StringBuilder sb = new StringBuilder();
        sb.append("https://m.weibo.cn/api/container/getIndex?type=all&queryVal=")
                .append(keywordParam)
                .append("&featurecode=20000320&luicode=10000011&lfid=100103type%3D1%26q%3D250&title=")
                .append(keywordParam)
                .append("&containerid=100103type%3D1%26q%3D")
                .append(keywordParam)
                .append("&page=")
                .append(page);
        String url = new String(sb);
        HttpGet request = new HttpGet(url);
        request.setHeader(HttpHeaders.USER_AGENT,UserAgents.STATIC_USER_AGENT);

        try {
            HttpResponse response = httpClient.execute(request);
            if (response.getStatusLine().getStatusCode() == HttpStatus.OK.value()) {
               return EntityUtils.toString(response.getEntity(), "GBK");
            }else {
                log.error("mobile search error , code {}", response.getStatusLine().getStatusCode());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            request.releaseConnection();
        }
        return null;
    }

    /**
     * 数据解析保存
     * @param jsonStr 搜索返回数据
     * @param userList 用户列表
     * @return 是否还有下一页
     */
    public static boolean searchDataClear(String keyword , String jsonStr , List<WeiboUser> userList){
        JsonObject jsonObject = new Gson().fromJson(jsonStr,JsonObject.class);
        Boolean ok = jsonObject.get("ok").getAsInt() == 1;
        JsonArray jsonArray = jsonObject.getAsJsonObject("data").getAsJsonArray("cards");
        jsonArray.forEach(p->{
            Integer showType = p.getAsJsonObject().get("show_type").getAsInt();
            JsonElement title = p.getAsJsonObject().get("title");
            //第一页存在多个card  以title鉴别 后续页面只有一个card
            if(showType == 1 && (title != null || jsonArray.size()==1)){
               JsonObject object = p.getAsJsonObject();
               JsonArray cardGroups = object.getAsJsonArray("card_group");
                cardGroups.forEach(m -> {

                    JsonObject mBlog = m.getAsJsonObject().getAsJsonObject("mblog");
                    JsonObject user = mBlog.get("user").getAsJsonObject();
                    String uid = user.get("id").getAsString();
                    if(bloomFilter.mightContain(uid)){
                        //log.warn("用户：{} 已存在",uid);
                        return;
                    }
                    String nickName = user.get("screen_name").getAsString();
                    String source = mBlog.get("source").getAsString();
                    String avatar = user.get("avatar_hd").getAsString();
                    String gender = user.get("gender").getAsString().trim();
                    String createdAt = mBlog.get("created_at").getAsString();
                    Integer followersCount = user.get("followers_count").getAsInt();
                    Integer followCount = user.get("follow_count").getAsInt();
                    String originText = mBlog.get("text").getAsString();
                    String simpleText = mBlog.get("text").getAsString().replaceAll("<[^>]+>","");
                    WeiboUser weiboUser = new WeiboUser();
                    weiboUser.setUid(uid);
                    weiboUser.setNickName(nickName);
                    weiboUser.setGender(gender);
                    weiboUser.setAvatar(avatar);
                    weiboUser.setSource(source);
                    weiboUser.setFollowCount(followCount);
                    weiboUser.setFollowersCount(followersCount);
                    weiboUser.setSimpleText(simpleText);
                    weiboUser.setOriginText(originText);
                    weiboUser.setCrtTime(new Date());
                    weiboUser.setCreatedAt(createdAt);
                    weiboUser.setAddBy(keyword);
                    userList.add(weiboUser);
                    //mobileDetailSearch(weiboUser);
                    bloomFilter.put(uid);
                });
            }
        });
        return ok;
    }

    /**
     * 获取详细用户信息
     * @param weiboUser
     * @return
     */
    private static void mobileDetailSearch(WeiboUser weiboUser){
        String detailResponse = sendDetailInfoRequest(weiboUser.getUid());
        JsonObject detailJson = new Gson().fromJson(detailResponse,JsonObject.class);
        JsonArray cards = detailJson.getAsJsonObject("data").getAsJsonArray("cards");
        cards.forEach(p->{
            JsonObject itemJsonObj = p.getAsJsonObject();
            String itemName = itemJsonObj.get("item_name").getAsString();
            if("昵称".equals(itemName)){
                weiboUser.setNickName(itemJsonObj.get("item_content").getAsString());
            } else if("所在地".equals(itemName)){
                weiboUser.setPosition(itemJsonObj.get("item_content").getAsString());
            } else if("简介".equals(itemName)){
                weiboUser.setDescription(itemJsonObj.get("item_content").getAsString());
            } else if("性别".equals(itemName)){
                weiboUser.setGender(itemJsonObj.get("item_content").getAsString());
            } else if("注册时间".equals(itemName)){
                try {
                    DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
                    Date date = format1.parse(itemJsonObj.get("item_content").getAsString());
                    weiboUser.setRegistrationTime(date);
                } catch (ParseException e) {
                    log.error("日期转换错误:{}",itemJsonObj.get("item_content").getAsString());
                }
            }
        });

    }

    /**
     * 请求用户详细信息
     * @param uid
     * @return
     */
    private static String sendDetailInfoRequest(String uid){
        StringBuilder sb = new StringBuilder();
        sb.append("https://m.weibo.cn/api/container/getIndex?containerid=230283")
                .append(uid)
                .append("_-_INFO&title=%25E5%259F%25BA%25E6%259C%25AC%25E8%25B5%2584%25E6%2596%2599&luicode=10000011&lfid=230283")
                .append(uid)
                .append("&featurecode=20000320");
        String url = new String(sb);
        log.debug("用户详细信息：{}",url);
        HttpGet request = new HttpGet(url);
        try {

            request.setHeader(HttpHeaders.USER_AGENT,UserAgents.STATIC_USER_AGENT);
            HttpResponse response = null;
            response = httpClient.execute(request);

            if (response.getStatusLine().getStatusCode() == HttpStatus.OK.value()) {
                return EntityUtils.toString(response.getEntity(), "GBK");
            }else {
                log.error("mobile search error , code {}", response.getStatusLine().getStatusCode());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            request.releaseConnection();
        }
        return null;
    }

}
